package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpecParamDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class  SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {

    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SpecParamService paramService;
    @Autowired
    private SpuDetailService detailService;
    @Autowired
    private SkuService skuService;

    //@Override
    public PageDTO<SpuDTO> pageQuery(Integer page, Integer rows, Long id, Long cid, Long bid, Boolean saleable) {
        IPage<Spu> iPage = new Page<>(page,rows);
        //select * from tb_spu [where id = #{id} and cid3= #{cid} and brand_id = #{bid} and saleable=#{saleable}] limit 0,5
        page(iPage,new QueryWrapper<Spu>()
                .eq(null!=id,"id",id)
                .eq(null!=cid,"cid3",cid)
                .eq(null!=bid,"brand_id",bid)
                .eq(null!=saleable,"saleable",saleable)
        );
        //执行分页查询以及封装
        List<SpuDTO> spuDTOS = SpuDTO.convertEntityList(iPage.getRecords());
        //循环给每个spuDTO添加brandName以及categoryName
        spuDTOS.forEach(spuDTO -> {
            spuDTO.setBrandName(this.brandService.getById(spuDTO.getBrandId()).getName());
            String names = this.categoryService.listByIds(spuDTO.getCategoryIds())
                    .stream()
                    .map(Category::getName)
                    .collect(Collectors.joining("/"));//name1/name2/name3
            spuDTO.setCategoryName(names);
        });
        return new PageDTO<>(iPage.getTotal(),iPage.getPages(),spuDTOS);
    }

    @Override
    public List<SpecParamDTO> queryParam(Long id, Boolean searching) {

        Long cateGoryId = this.getById(id).getCid3();

        //select * from tb_spec_param where category_id = #{categoryId} [and searching = #{searching}]
        List<SpecParamDTO> specParamDTOS = SpecParamDTO.convertEntityList(this.paramService.query()
                .eq("category_id", cateGoryId)
                .eq(null != searching, "searching", searching)
                .list());
        //key ==>paramId,value,就是需要的value
        Map<Long,Object> paramValueMap =
                JsonUtils.nativeRead(
                        this.detailService.getById(id).getSpecification(),
                        new TypeReference<Map<Long, Object>>() {
                        });


        specParamDTOS.forEach(specParamDTO -> {
            Long paramId = specParamDTO.getId();
            specParamDTO.setValue(paramValueMap.get(paramId));
        });

        return specParamDTOS;
    }


    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    @Transactional
    public void modifySaleable(Long id, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        //update tb_spu set saleable = #{saleable} where id = #{id}
        updateById(spu);

        Sku sku = new Sku();
        sku.setSaleable(saleable);

        //update tb_sku set saleable = #{saleable} where spu_id = #{id} and saleable = !#{saleable}
        this.skuService.update(sku, new QueryWrapper<Sku>()
                .eq("spu_id", id)
                .eq("saleable", !saleable)
        );

        //saleable为true表示上架，为false表示下架
        String routingKey = saleable ? "up" : "down";

        this.amqpTemplate.convertAndSend("jhj", routingKey, spu.getId());
    }


    @Override
    public SpuDTO queryGoodsById(Long id) {

        SpuDTO spuDTO = this.pageQuery(1, 1, id, null, null, null).getItems().get(0);

        //根据spuId查询对应的spuDetail
        spuDTO.setSpuDetail(new SpuDetailDTO(this.detailService.getById(id)));
        //根据spuId查询对应的sku集合，List<Entity>==>List<DTO>
        spuDTO.setSkus(SkuDTO.convertEntityList(this.skuService.query().eq("spu_id",id).list()));

        return spuDTO;
    }

    @Override
    public SpuDTO querySpuById(Long id) {
        return new SpuDTO(this.getById(id));
    }


}
